package com.ruoyi.cinema.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.cinema.BO.*;
import com.ruoyi.cinema.DTO.*;
import com.ruoyi.cinema.domain.FilmSchedule;
import com.ruoyi.order.domain.OrderPromotion;
import com.ruoyi.cinema.domain.ScheduleAreaInfo;
import com.ruoyi.cinema.domain.SchedulePromoArea;
import com.ruoyi.cinema.mapper.FilmScheduleMapper;
import com.ruoyi.cinema.mapper.ScheduleAreaInfoMapper;
import com.ruoyi.cinema.mapper.SchedulePromoMapper;
import com.ruoyi.cinema.service.IFilmScheduleService;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.uuid.IdUtils;
import com.ruoyi.constant.OrderConstant;
import com.ruoyi.utils.YzResult;
import com.ruoyi.utils.YzUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 影片排期Service业务层处理
 *
 * @author HHAOYU
 * @date 2020-12-08
 */
@Service
public class FilmScheduleServiceImpl extends ServiceImpl<FilmScheduleMapper, FilmSchedule> implements IFilmScheduleService  {
    @Autowired
    private FilmScheduleMapper filmScheduleMapper;
    @Autowired
    private RedisCache redisCache;
    @Autowired
    private SchedulePromoMapper schedulePromoMapper;
    @Autowired
    private ScheduleAreaInfoMapper scheduleAreaInfoMapper;



    /**
     * 查询影片排期
     *
     * @param id 影片排期ID
     * @return 影片排期
     */
    @Override
    public FilmSchedule selectFilmScheduleById(Long id)
    {
        return filmScheduleMapper.selectFilmScheduleById(id);
    }

    /**
     * 查询影片排期列表
     *
     * @param filmSchedule 影片排期
     * @return 影片排期
     */
    @Override
    public List<FilmSchedule> selectFilmScheduleList(FilmSchedule filmSchedule)
    {
        return filmScheduleMapper.selectFilmScheduleList(filmSchedule);
    }

    /**
     * 新增影片排期
     *
     * @param filmSchedule 影片排期
     * @return 结果
     */
    @Override
    public int insertFilmSchedule(FilmSchedule filmSchedule)
    {
        return filmScheduleMapper.insertFilmSchedule(filmSchedule);
    }

    /**
     * 修改影片排期
     *
     * @param filmSchedule 影片排期
     * @return 结果
     */
    @Override
    public int updateFilmSchedule(FilmSchedule filmSchedule)
    {
        return filmScheduleMapper.updateFilmSchedule(filmSchedule);
    }

    /**
     * 批量删除影片排期
     *
     * @param ids 需要删除的影片排期ID
     * @return 结果
     */
    @Override
    public int deleteFilmScheduleByIds(Long[] ids)
    {
        return filmScheduleMapper.deleteFilmScheduleByIds(ids);
    }

    /**
     * 删除影片排期信息
     *
     * @param id 影片排期ID
     * @return 结果
     */
    @Override
    public int deleteFilmScheduleById(Long id)
    {
        return filmScheduleMapper.deleteFilmScheduleById(id);
    }


    @Override
    public SeatPlanYzDTO getScheduleHallSeat(FilmSchedule filmSchedule){
       YzResult<SectionSeatSoldDTO> sectionSeatSoldDTOResult =  YzUtils.getScheduleSoldSeatList(filmSchedule.getCinemaLinkId(),filmSchedule.getScheduleId(),"",filmSchedule.getScheduleKey());
        String s= redisCache.getCacheMapValue(filmSchedule.getCinemaLinkId()+ Constants.CINEMA_HALL,filmSchedule.getHallCode());
        SeatPlanYZALLDTO seatPlanYZALLDTO = JSON.parseObject(s,SeatPlanYZALLDTO.class);
        SeatPlanYzDTO seatPlanYzDTO = seatPlanYZALLDTO.getSeatPlanList().get(0);

        String areaJson = redisCache.getCacheMapValue(Constants.SCHEDULE_AREA_HALL_MAP,filmSchedule.getScheduleId());
        AreaSeatPlanYZALLDTO areaSeatPlanYZALLDTO = JSON.parseObject(areaJson,AreaSeatPlanYZALLDTO.class);
        Map<String,AreaInfoYzDTO> areaSeatMap = null;

        if(     null != areaSeatPlanYZALLDTO &&
                null != areaSeatPlanYZALLDTO.getAreaSeatPlanList() &&
                !areaSeatPlanYZALLDTO.getAreaSeatPlanList().isEmpty() &&
                null != areaSeatPlanYZALLDTO.getAreaSeatPlanList().get(0).getSectionAreaList()
        ){
            List<AreaSeatSectionYzDTO> assydl = areaSeatPlanYZALLDTO.getAreaSeatPlanList().get(0).getSectionAreaList();
            areaSeatMap = new HashMap<>();
            for (AreaSeatSectionYzDTO assyd :assydl) {
                List<AreaInfoYzDTO> areaInfoList =  assyd.getAreaInfoList();
                for (AreaInfoYzDTO aiyd :areaInfoList) {
                    for (AreaSeatDTO asd :aiyd.getSeatList()) {
                        areaSeatMap.put(asd.getSeatCode(),aiyd);
                    }
                }
            }
        }
        if(sectionSeatSoldDTOResult.getResultCode().equals(200) && sectionSeatSoldDTOResult.getData().getBizCode().equals("SUCCESS")){
               List<SectionSeatSoldDTO> sssdl =  sectionSeatSoldDTOResult.getData().getBizDataList();
           // 将座位加上当前状态
            if(null != sssdl){
                Map<String, Map<String,String>> sectionSeatsMap = new HashMap<>();
                for (SectionSeatSoldDTO sd :sssdl) {
                    List<SoldSeatYzDTO> soldSeatList = sd.getSoldSeatList();
                    Map<String, String > seatMap  = new HashMap<>();
                    sectionSeatsMap.put(sd.getSectionCode(),seatMap);
                    for (SoldSeatYzDTO ssy :soldSeatList) {
                        seatMap.put(ssy.getSeatCode(),ssy.getSeatStatus());
                    }
                }
                List<SectionYZDTO> sectionList = seatPlanYzDTO.getSectionList();
                Map<String,String> areaIdIndexMap = new HashMap<>();
                ScheduleAreaInfo scheduleAreaInfo = new ScheduleAreaInfo();
                scheduleAreaInfo.setScheduleId(filmSchedule.getId());
                List<ScheduleAreaInfo> scheduleAreaInfoList = scheduleAreaInfoMapper.selectScheduleAreaInfoList(scheduleAreaInfo);
                Integer index = 0;
                for (ScheduleAreaInfo sai :scheduleAreaInfoList) {
                    areaIdIndexMap.put(sai.getAreaId(),String.valueOf(index));
                    index++;
                }

                for (SectionYZDTO syd :sectionList) {
                    Map<String,String> seatStatusMap = sectionSeatsMap.getOrDefault(syd.getSectionCode(),new HashMap<>());

                    for (Seat st :syd.getSeatList()) {
                        if(null != areaSeatMap){
                            if(areaSeatMap.containsKey(st.getSeatCode())){
                                AreaInfoYzDTO areaInfoYzDTO = areaSeatMap.get(st.getSeatCode());
                                st.setAreaId(areaInfoYzDTO.getAreaId());
                                st.setAreaName(areaInfoYzDTO.getAreaName());
                            }else {
                                st.setAreaId("0");
                                st.setAreaName("普通区");
                            }
                            st.setSeatColorIndex(areaIdIndexMap.get(st.getAreaId()));
                        }else {
                            st.setAreaId("0");
                            st.setAreaName("普通区");
                        }

                        st.setSeatStatus(seatStatusMap.getOrDefault(st.getSeatCode(), "OK"));
                    }
                }
            }

            // 将座位图转化为2维数组
            List<SectionYZDTO> sectionList = seatPlanYzDTO.getSectionList();
            for (SectionYZDTO syd :sectionList) {
                int maxX = 0;
                int maxY = 0;
                for (Seat st :syd.getSeatList()) {
                    int x = Integer.parseInt(st.getxCoord());
                    if( maxX < x){
                        maxX = x;
                    }
                    int y = Integer.parseInt(st.getyCoord());
                    if(maxY < y){
                        maxY = y;
                    }
                }
                Seat[][] seat2DList = new Seat[maxY+1][maxX+1];

                for (Seat st :syd.getSeatList()) {
                    int x = Integer.parseInt(st.getxCoord());
                    int y = Integer.parseInt(st.getyCoord());
                    seat2DList[y][x] = st;
                }
                syd.setSeatList(null);
                syd.setSeat2DList(seat2DList);
            }


        }
        return seatPlanYzDTO;

    }

    @Override
    public List<FilmSchedule> selectFilmScheduleForApi(FilmScheduleBO filmScheduleBO) {
        List<FilmSchedule> filmScheduleList = filmScheduleMapper.selectFilmScheduleForApi(filmScheduleBO);
        if(null != filmScheduleList && !filmScheduleList.isEmpty()) {
            List<String> scheduleIdList = filmScheduleList.stream().map(FilmSchedule::getScheduleId).collect(Collectors.toList());
            Map<String, List<AreaPromoYzDTO>> scheduleIdAreaMap = null;
            if (null != filmScheduleBO.getAccessToken()) {
                YzResult<SchedulePromoYzDTO> schedulePromoList = YzUtils.getSchedulePromoList(filmScheduleBO.getCinemaLinkId(), scheduleIdList, filmScheduleBO.getAccessToken());
                if (schedulePromoList.getResultCode().equals(Constants.YZSUCCESS) && schedulePromoList.getData().getBizCode().equals(Constants.BIZSUCCESS)) {
                    List<SchedulePromoYzDTO> schedulePromoYzDTOList = schedulePromoList.getData().getBizDataList();
                    if (null != schedulePromoYzDTOList && !schedulePromoYzDTOList.isEmpty()) {
                        scheduleIdAreaMap = new HashMap<>();
                        for (SchedulePromoYzDTO spy : schedulePromoYzDTOList) {
                            if (!scheduleIdAreaMap.containsKey(spy.getScheduleId())) {
                                scheduleIdAreaMap.put(spy.getScheduleId(), spy.getAreaPromoList());
                            } else {
                                scheduleIdAreaMap.get(spy.getScheduleId()).addAll(spy.getAreaPromoList());
                            }
                        }
                    }
                }
            }
            for (FilmSchedule fs : filmScheduleList) {

                if (null != fs.getScheduleAreaInfoList() && !fs.getScheduleAreaInfoList().isEmpty()) {
                    Long lowPrice = Long.MAX_VALUE;
                    for (ScheduleAreaInfo sai : fs.getScheduleAreaInfoList()) {
                        Long price = sai.getAreaSettlePrice() + StringUtils.nullTo0(sai.getAreaServiceFee()) + StringUtils.nullTo0(fs.getTicketFee());
                        if (lowPrice > price) {
                            lowPrice = price;
                        }
                    }
                    fs.setTicketRealPrice(lowPrice);
                }

                if (null != scheduleIdAreaMap && !scheduleIdAreaMap.isEmpty()) {
                    List<AreaPromoYzDTO> areaPromoYzDTOList = scheduleIdAreaMap.get(fs.getScheduleId());
                    if (null != areaPromoYzDTOList && !areaPromoYzDTOList.isEmpty()) {
                        Long lowPrice = Long.MAX_VALUE;
                        for (AreaPromoYzDTO spa : areaPromoYzDTOList) {
                            if (lowPrice > spa.getPromoPrice()) {
                                lowPrice = spa.getPromoPrice();
                            }
                        }
                        fs.setTicketActivityPrice(lowPrice);
                        fs.setSchedulePromoAreaList(null);
                    }
                } else {
                    if (null != fs.getSchedulePromoAreaList() && !fs.getSchedulePromoAreaList().isEmpty()) {
                        long lowPrice = Long.MAX_VALUE;
                        Long lowPricePromoId = 0L;
                        String promoTag = "";
                        for (SchedulePromoArea spa : fs.getSchedulePromoAreaList()) {
                            if (lowPrice > Long.parseLong(spa.getPromoPrice())) {
                                lowPrice = Long.parseLong(spa.getPromoPrice());
                                lowPricePromoId = spa.getSchedulePromoId();
                                promoTag = spa.getPromoTag();
                            }
                        }
                        fs.setTicketActivityPrice(lowPrice);
                        fs.setTicketLowActivityPromoId(lowPricePromoId);
                        fs.setPromoTag(promoTag);
                        fs.setSchedulePromoAreaList(null);
                    }
                }
                fs.setEndDateTime(DateUtils.addMinutes(fs.getShowDateTime(), fs.getDuration().intValue()));
            }
        }
        return filmScheduleList;
    }

    @Override
    public List<CanUsePriceBO> getCanUsePrice(GetEffectivePromoBO gepb , LockSeatBO ls){

        List<CanUsePriceBO> canUsePriceBOList = new LinkedList<>();
        ScheduleAreaInfo scheduleAreaInfo = new ScheduleAreaInfo();
        scheduleAreaInfo.setScheduleId(ls.getId());
        List<ScheduleAreaInfo> scheduleAreaInfoList= scheduleAreaInfoMapper.selectScheduleAreaInfoList(scheduleAreaInfo);
        Map<String,ScheduleAreaInfo> scheduleAreaInfoMap = scheduleAreaInfoList.stream().collect(Collectors.toMap(ScheduleAreaInfo::getAreaId, sai ->sai));
        FilmSchedule fs = filmScheduleMapper.selectFilmScheduleById(ls.getId());
        for (EffectivePromoTicketYzDTO epty :gepb.getTicketList()) {
            epty.setScheduleId(fs.getScheduleId());
        }

        CanUsePriceBO original = new CanUsePriceBO();
        long orderAmount = 0L;
        long originalTotalTicketPrice = 0L;
        long originalTotalServiceFee = 0L;
        long originalTotalTicketFee = 0L;
        for (SeatAndAreaBO sab :ls.getSeatCodeList()) {
            ScheduleAreaInfo sai = scheduleAreaInfoMap.get(sab.getAreaId());
            originalTotalTicketPrice += StringUtils.nullTo0(sai.getAreaSettlePrice());
            originalTotalServiceFee += StringUtils.nullTo0(sai.getAreaServiceFee());
        }
        if(fs.getFeeType().equals("ticket")){
            originalTotalTicketFee += (StringUtils.nullTo0(fs.getTicketFee()) * ls.getSeatCodeList().size());
        }else {
            originalTotalTicketFee += StringUtils.nullTo0(fs.getTicketFee());
        }
        orderAmount = originalTotalTicketPrice + originalTotalServiceFee + originalTotalTicketFee;
        original.setOrderAmount(orderAmount);
        original.setPayAmount(orderAmount);
        original.setCanUse(true);
        original.setPayType(CanUsePriceBO.BOOTH);
        original.setPromoTag("无优惠");
        original.setPromoAmount(0L);
        List<OrderTicketBO> orderTicketBOList = new ArrayList<>(ls.getSeatCodeList().size());
        List<SeatAndAreaBO> seatAndAreaBOList = ls.getSeatCodeList();
        for (SeatAndAreaBO saab :seatAndAreaBOList) {
            OrderTicketBO otb = new OrderTicketBO();
            otb.setSeatCode(saab.getSeatCode());
            orderTicketBOList.add(otb);
        }
        original.setTicketList(orderTicketBOList);

        YzResult<CardInfoYzDTO> cardInfoYzDTOResult = YzUtils.getCardList(gepb.getAccessToken());
        Map<String,CardInfoYzDTO> cardInfoYzDTOMap = null;
        if(cardInfoYzDTOResult.getResultCode().equals(Constants.YZSUCCESS) && cardInfoYzDTOResult.getData().getBizCode().equals(Constants.BIZSUCCESS)){
            List<CardInfoYzDTO> cardInfoYzDTOList =  cardInfoYzDTOResult.getData().getBizDataList();
            if(null != cardInfoYzDTOList && !cardInfoYzDTOList.isEmpty()){
                cardInfoYzDTOMap = cardInfoYzDTOList.stream().collect(Collectors.toMap(CardInfoYzDTO::getCardNo,cardInfoYzDTO -> cardInfoYzDTO));
            }
        }
        gepb.setCinemaLinkId(ls.getCinemaLinkId());
        YzResult<EffectivePromoAllYzDTO> effectivePromoAllYzDTOResult = YzUtils.getEffectivePromoList(gepb);


        if(effectivePromoAllYzDTOResult.getResultCode().equals(Constants.YZSUCCESS) && effectivePromoAllYzDTOResult.getData().getBizCode().equals(Constants.BIZSUCCESS)) {
            EffectivePromoAllYzDTO efpayd = effectivePromoAllYzDTOResult.getData().getBizData();
            if(null != efpayd && null != efpayd.getPromoList()) {
                List<EffectivePromoYzDTO> effectivePromoYzDTOList = efpayd.getPromoList();
                for (EffectivePromoYzDTO epy : effectivePromoYzDTOList) {
                    CanUsePriceBO canUsePriceBO = new CanUsePriceBO();
                    /** 若有卡优惠可用 */
                    if (null != epy.getCardList() && !epy.getCardList().isEmpty()) {
                        EffectiveCardYzDTO ecyd = epy.getCardList().get(0);
                        /** 若为储值卡*/
                        if (ecyd.getCardType().equals("DEPOSIT")) {
                            canUsePriceBO.setPromoTag(ecyd.getCardRuleName());
                            if (null == epy.getPromoActivityList() || epy.getPromoActivityList().isEmpty()) {
                                canUsePriceBO.setOrderAmount(epy.getPromoPrice());
                                canUsePriceBO.setPayAmount(canUsePriceBO.getOrderAmount());
                                canUsePriceBO.setPromoAmount(0L);

                            } else {
                                Long om = StringUtils.nullTo0(epy.getOriginalTotalTicketPrice()) +
                                        StringUtils.nullTo0(epy.getOriginalTotalServiceFee()) +
                                        StringUtils.nullTo0(epy.getOriginalTotalTicketFee());
                                canUsePriceBO.setOrderAmount(om);
                                canUsePriceBO.setPayAmount(epy.getPromoPrice());
                                canUsePriceBO.setPromoAmount(canUsePriceBO.getOrderAmount() - canUsePriceBO.getPayAmount());
                                OrderPromotion orderPromotion = new OrderPromotion();
                                orderPromotion.setPromoType(OrderConstant.PROMO_TYPE_ACTIVITY);
                                orderPromotion.setPromoCode(epy.getPromoActivityList().get(0).getActivityCode());
                                orderPromotion.setPromoAmount(canUsePriceBO.getPromoAmount());
                                List<OrderPromotion> orderPromotionList = new ArrayList<>(1);
                                orderPromotionList.add(orderPromotion);
                                canUsePriceBO.setPromotionList(orderPromotionList);
                                canUsePriceBO.setPromoTag(ecyd.getCardRuleName()+"专享-"+epy.getPromoActivityList().get(0).getActivityTag());
                            }
                            if (null != cardInfoYzDTOMap) {
                                CardInfoYzDTO cardInfoYzDTO = cardInfoYzDTOMap.get(ecyd.getCardNo());
                                if (cardInfoYzDTO.getCardAmount() < canUsePriceBO.getPayAmount()) {
                                    canUsePriceBO.setCanUse(false);
                                    canUsePriceBO.setPayType(CanUsePriceBO.MEMBER_CARD_PAY);
                                    canUsePriceBO.setCanNotUseReason("余额不足");
                                } else {
                                    canUsePriceBO.setCanUse(true);
                                    canUsePriceBO.setPayType(CanUsePriceBO.MEMBER_CARD_PAY);
                                    List<EffectiveTicketPromoYzDTO> eptydList = epy.getTicketPromoList();
                                    List<OrderTicketBO> otbList = new ArrayList<>(eptydList.size());
                                    for (EffectiveTicketPromoYzDTO eptyd : eptydList) {
                                        OrderTicketBO orderTicketBO = new OrderTicketBO();
                                        orderTicketBO.setSeatCode(eptyd.getSeatCode());
                                        if (null != epy.getPromoActivityList() && !epy.getPromoActivityList().isEmpty()) {
                                            orderTicketBO.setActivityCode(eptyd.getPromoCode());
                                        }
                                        otbList.add(orderTicketBO);
                                    }
                                    canUsePriceBO.setTicketList(otbList);
                                }
                            }
                            List<PayTypeBo> payTypeBoList = new ArrayList<>(1);
                            PayTypeBo payTypeBo = new PayTypeBo();
                            payTypeBo.setPayType(PayTypeBo.MEMBER_CARD_PAY);
                            payTypeBo.setCardNo(ecyd.getCardNo());
                            payTypeBo.setCardRuleName(ecyd.getCardRuleName());
                            payTypeBo.setPayAmount(canUsePriceBO.getPayAmount());
                            payTypeBo.setPayCode(ecyd.getCardNo());
                            payTypeBo.setPayMethodCode(OrderConstant.MEMBER_CARD);
                            payTypeBoList.add(payTypeBo);
                            canUsePriceBO.setPayTypeList(payTypeBoList);

                        }else {
                            /** 若为权益卡*/
                            //todo 现在只支持储值卡和权益卡 此种情况都认为为权益卡
                            Long om = StringUtils.nullTo0(epy.getOriginalTotalTicketPrice()) +
                                    StringUtils.nullTo0(epy.getOriginalTotalServiceFee()) +
                                    StringUtils.nullTo0(epy.getOriginalTotalTicketFee());
                            canUsePriceBO.setOrderAmount(om);
                            canUsePriceBO.setCanUse(true);
                            canUsePriceBO.setPayType(CanUsePriceBO.WEIXIN_PAY);
                            canUsePriceBO.setPayAmount(epy.getPromoPrice());
                            canUsePriceBO.setPromoAmount(canUsePriceBO.getOrderAmount() - canUsePriceBO.getPayAmount());

                            List<EffectiveTicketPromoYzDTO> eptydList = epy.getTicketPromoList();
                            List<OrderTicketBO> otbList = new ArrayList<>(eptydList.size());
                            for (EffectiveTicketPromoYzDTO eptyd : eptydList) {
                                OrderTicketBO orderTicketBO = new OrderTicketBO();
                                orderTicketBO.setSeatCode(eptyd.getSeatCode());
                                if (null != epy.getPromoActivityList() && !epy.getPromoActivityList().isEmpty()) {
                                    orderTicketBO.setActivityCode(eptyd.getPromoCode());
                                }
                                otbList.add(orderTicketBO);
                            }
                            canUsePriceBO.setTicketList(otbList);

                            if (null != epy.getPromoActivityList() && !epy.getPromoActivityList().isEmpty()) {
                                OrderPromotion orderPromotion = new OrderPromotion();
                                orderPromotion.setPromoType(OrderConstant.PROMO_TYPE_ACTIVITY);
                                orderPromotion.setPromoCode(epy.getPromoActivityList().get(0).getActivityCode());
                                orderPromotion.setPromoAmount(canUsePriceBO.getPromoAmount());

                                OrderPromotion opMember = new OrderPromotion();
                                opMember.setPromoType(OrderConstant.PROMO_TYPE_PRIVILEGE);
                                opMember.setPromoCode(ecyd.getCardNo());
                                opMember.setPromoAmount(0L);
                                List<OrderPromotion> orderPromotionList = new ArrayList<>(2);
                                orderPromotionList.add(orderPromotion);
                                orderPromotionList.add(opMember);
                                canUsePriceBO.setPromotionList(orderPromotionList);
                                canUsePriceBO.setPromoTag(ecyd.getCardRuleName()+"专享-"+epy.getPromoActivityList().get(0).getActivityTag());
                            }else {
                                OrderPromotion orderPromotion = new OrderPromotion();
                                orderPromotion.setPromoType(OrderConstant.PROMO_TYPE_MEMBER);
                                orderPromotion.setPromoCode(ecyd.getCardNo());
                                orderPromotion.setPromoAmount(canUsePriceBO.getPromoAmount());
                                List<OrderPromotion> orderPromotionList = new ArrayList<>(1);
                                orderPromotionList.add(orderPromotion);
                                canUsePriceBO.setPromotionList(orderPromotionList);
                                canUsePriceBO.setPromoTag(ecyd.getCardRuleName());
                            }
                            List<PayTypeBo> payTypeBoList = new ArrayList<>();
                            PayTypeBo payTypeBo = new PayTypeBo();
                            payTypeBo.setPayType(PayTypeBo.WEIXIN_PAY);
                            payTypeBo.setPayAmount(canUsePriceBO.getPayAmount());
                            payTypeBo.setPayCode(IdUtils.fastSimpleUUID());
                            payTypeBo.setPayMethodCode(OrderConstant.WEIXIN);
                            payTypeBoList.add(payTypeBo);
                            canUsePriceBO.setPayTypeList(payTypeBoList);


                        }
                    }else{
                        /** 若没有卡优惠可用 这时可用卡支付也可用微信支付 此时 如卡余额足够，则可选择卡支付*/
                        Long om = StringUtils.nullTo0(epy.getOriginalTotalTicketPrice()) +
                                StringUtils.nullTo0(epy.getOriginalTotalServiceFee()) +
                                StringUtils.nullTo0(epy.getOriginalTotalTicketFee());
                        canUsePriceBO.setOrderAmount(om);
                        canUsePriceBO.setCanUse(true);
                        canUsePriceBO.setPayType(CanUsePriceBO.BOOTH);
                        canUsePriceBO.setPayAmount(epy.getPromoPrice());
                        canUsePriceBO.setPromoAmount(canUsePriceBO.getOrderAmount() - canUsePriceBO.getPayAmount());
                        if (null != epy.getPromoActivityList() && !epy.getPromoActivityList().isEmpty()) {
                            OrderPromotion orderPromotion = new OrderPromotion();
                            orderPromotion.setPromoType(OrderConstant.PROMO_TYPE_ACTIVITY);
                            orderPromotion.setPromoCode(epy.getPromoActivityList().get(0).getActivityCode());
                            orderPromotion.setPromoAmount(canUsePriceBO.getPromoAmount());
                            List<OrderPromotion> orderPromotionList = new ArrayList<>(1);
                            orderPromotionList.add(orderPromotion);
                            canUsePriceBO.setPromotionList(orderPromotionList);
                            canUsePriceBO.setPromoTag(epy.getPromoActivityList().get(0).getActivityTag());
                        }

                        List<EffectiveTicketPromoYzDTO> eptydList = epy.getTicketPromoList();
                        List<OrderTicketBO> otbList = new ArrayList<>(eptydList.size());
                        for (EffectiveTicketPromoYzDTO eptyd : eptydList) {
                            OrderTicketBO orderTicketBO = new OrderTicketBO();
                            orderTicketBO.setSeatCode(eptyd.getSeatCode());
                            if (null != epy.getPromoActivityList() && !epy.getPromoActivityList().isEmpty()) {
                                orderTicketBO.setActivityCode(eptyd.getPromoCode());
                            }
                            otbList.add(orderTicketBO);
                        }
                        canUsePriceBO.setTicketList(otbList);

                    }
                    if(null !=canUsePriceBO.getPayAmount() && null != canUsePriceBO.getPromoTag()){
                        canUsePriceBOList.add(canUsePriceBO);
                    }
                }
            }
            if(null != efpayd && null != efpayd.getCouponPromo() && null != efpayd.getCouponPromo().getCouponList()){
                List<EffectiveCouponYzDTO> allCoupon = efpayd.getCouponPromo().getCouponList();
                if(!allCoupon.isEmpty()){
                    for (EffectiveCouponYzDTO ecyd :allCoupon) {
                        if(ecyd.getCanUse().equals("Y")){
                            CanUsePriceBO canUsePriceBO = new CanUsePriceBO();
                            canUsePriceBO.setCanUse(true);
                            canUsePriceBO.setOrderAmount(original.getOrderAmount());
                            canUsePriceBO.setPayAmount(canUsePriceBO.getOrderAmount());
                            canUsePriceBO.setPromoAmount(0L);
                            canUsePriceBO.setPayType(CanUsePriceBO.WEIXIN_PAY);
                            canUsePriceBO.setPromoTag(ecyd.getCouponName()+":"+ecyd.getCouponCode() +"减免金额"+(ecyd.getCouponPromoPrice()/100));
                            PayTypeBo couponPay = new PayTypeBo();
                            couponPay.setPayAmount(ecyd.getCouponPromoPrice());
                            couponPay.setPayMethodCode(OrderConstant.COUPON);
                            couponPay.setPayMethodId(IdUtils.fastSimpleUUID());
                            couponPay.setPayMethodName("优惠券");
                            couponPay.setPayCode(ecyd.getCouponCode());
                            couponPay.setPayApply("TICKET");
                            canUsePriceBO.setCouponPay(couponPay);
                            canUsePriceBO.setTicketList(orderTicketBOList);
                            //todo 先测试礼券的微信补差
                            List<PayTypeBo> ptbl = new ArrayList<>();
                            PayTypeBo payTypeBo = new PayTypeBo();
                            payTypeBo.setPayType(PayTypeBo.WEIXIN_PAY);
                            payTypeBo.setPayAmount(canUsePriceBO.getPayAmount()-couponPay.getPayAmount());
                            payTypeBo.setPayCode(IdUtils.fastSimpleUUID());
                            payTypeBo.setPayMethodCode(OrderConstant.WEIXIN);
                            ptbl.add(payTypeBo);
                            canUsePriceBO.setPayTypeList(ptbl);
                            canUsePriceBOList.add(canUsePriceBO);
                        }
                    }
                }

            }
        }
        /** 加入原始价格*/
        canUsePriceBOList.add(original);
        for (CanUsePriceBO cpb :canUsePriceBOList) {
            if(null == cpb.getPayTypeList() || cpb.getPayTypeList().isEmpty()){
                List<PayTypeBo> payTypeBoList = new ArrayList<>();
                PayTypeBo payTypeBo = new PayTypeBo();
                payTypeBo.setPayType(PayTypeBo.WEIXIN_PAY);
                payTypeBo.setPayAmount(cpb.getPayAmount());
                payTypeBo.setPayCode(IdUtils.fastSimpleUUID());
                payTypeBo.setPayMethodCode(OrderConstant.WEIXIN);
                payTypeBoList.add(payTypeBo);
                if(null != cardInfoYzDTOMap){
                    for (CardInfoYzDTO cardInfoYzDTO : cardInfoYzDTOMap.values()) {
                        if(cardInfoYzDTO.getCardType().equals("DEPOSIT")){
                            if(cardInfoYzDTO.getCardAmount() > cpb.getPayAmount()){
                                PayTypeBo ptb = new PayTypeBo();
                                ptb.setPayType(PayTypeBo.MEMBER_CARD_PAY);
                                ptb.setCardNo(cardInfoYzDTO.getCardNo());
                                ptb.setCardRuleName(cardInfoYzDTO.getCardRuleName());
                                ptb.setPayAmount(cpb.getPayAmount());
                                ptb.setPayCode(cardInfoYzDTO.getCardNo());
                                ptb.setPayMethodCode(OrderConstant.MEMBER_CARD);
                                payTypeBoList.add(ptb);
                            }
                        }

                    }
                }
                cpb.setPayTypeList(payTypeBoList);
            }
        }
        canUsePriceBOList.sort((Comparator.comparing(CanUsePriceBO::getPayAmount)));
        return canUsePriceBOList;

    }
}
